{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# Attachments\n",
    "\n",
    "## Setting Up the Environment\n",
    "\n",
    "Before diving into the code, we make sure our Kotlin Notebook is ready.\n",
    "Here we load the latest descriptors and enable the **Koog** library,\n",
    "which provides a clean API for working with AI model providers.\n"
   ]
  },
  {
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-08-15T10:27:17.953537Z",
     "start_time": "2025-08-15T10:27:17.766921Z"
    }
   },
   "cell_type": "code",
   "source": [
    "// Loads the latest descriptors and activates Koog integration for Kotlin Notebook.\n",
    "// This makes Koog DSL types and executors available in further cells.\n",
    "%useLatestDescriptors\n",
    "%use koog"
   ],
   "outputs": [],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Configuring API Keys\n",
    "\n",
    "We read the API key from an environment variable. This keeps secrets out of the notebook file and lets you\n",
    "switch providers. You can set `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `GEMINI_API_KEY`."
   ]
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-15T08:59:12.987077Z",
     "start_time": "2025-08-15T08:59:12.940253Z"
    }
   },
   "cell_type": "code",
   "source": "val apiKey = System.getenv(\"OPENAI_API_KEY\") // or ANTHROPIC_API_KEY, or GEMINI_API_KEY",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Creating a Simple OpenAI Executor\n",
    "\n",
    "The executor encapsulates authentication, base URLs, and correct defaults. Here we use a simple OpenAI executor,\n",
    "but you can swap it for Anthropic or Gemini without changing the rest of the code."
   ]
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-15T09:00:40.093638Z",
     "start_time": "2025-08-15T09:00:40.061716Z"
    }
   },
   "cell_type": "code",
   "source": [
    "// --- Provider selection ---\n",
    "// For OpenAI-compatible models. Alternatives include:\n",
    "//   val executor = simpleAnthropicExecutor(System.getenv(\"ANTHROPIC_API_KEY\"))\n",
    "//   val executor = simpleGeminiExecutor(System.getenv(\"GEMINI_API_KEY\"))\n",
    "// All executors expose the same high‑level API.\n",
    "val executor = simpleOpenAIExecutor(apiKey)"
   ],
   "outputs": [],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "Koog’s prompt DSL lets you add **structured Markdown** and **attachments**.\n",
    "In this cell we build a prompt that asks the model to generate a short, blog‑style \"content card\" and\n",
    "we attach two images from the local `images/` directory."
   ]
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-15T09:00:08.711759Z",
     "start_time": "2025-08-15T09:00:08.574211Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import ai.koog.prompt.markdown.markdown\n",
    "import kotlinx.io.files.Path\n",
    "\n",
    "val prompt = prompt(\"images-prompt\") {\n",
    "    system(\"You are professional assistant that can write cool and funny descriptions for Instagram posts.\")\n",
    "\n",
    "    user {\n",
    "        markdown {\n",
    "            +\"I want to create a new post on Instagram.\"\n",
    "            br()\n",
    "            +\"Can you write something creative under my instagram post with the following photos?\"\n",
    "            br()\n",
    "            h2(\"Requirements\")\n",
    "            bulleted {\n",
    "                item(\"It must be very funny and creative\")\n",
    "                item(\"It must increase my chance of becoming an ultra-famous blogger!!!!\")\n",
    "                item(\"It not contain explicit content, harassment or bullying\")\n",
    "                item(\"It must be a short catching phrase\")\n",
    "                item(\"You must include relevant hashtags that would increase the visibility of my post\")\n",
    "            }\n",
    "        }\n",
    "\n",
    "        attachments {\n",
    "            image(Path(\"images/kodee-loving.png\"))\n",
    "            image(Path(\"images/kodee-electrified.png\"))\n",
    "        }\n",
    "    }\n",
    "}"
   ],
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Execute and Inspect the Response\n",
    "\n",
    "We run the prompt against `gpt-4.1`, collect the first message, and print its content.\n",
    "If you want streaming, swap to a streaming API in Koog; for tool use, pass your tool list instead of `emptyList()`.\n",
    "\n",
    "> Troubleshooting:\n",
    "> * **401/403** — check your API key/environment variable.\n",
    "> * **File not found** — verify the `images/` paths.\n",
    "> * **Rate limits** — add minimal retry/backoff around the call if needed."
   ]
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-15T10:17:41.707125Z",
     "start_time": "2025-08-15T10:17:38.033937Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import kotlinx.coroutines.runBlocking\n",
    "\n",
    "runBlocking {\n",
    "    val response = executor.execute(prompt = prompt, model = OpenAIModels.Chat.GPT4_1, tools = emptyList()).first()\n",
    "    println(response.content)\n",
    "}"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Caption:\n",
      "Running on cuteness and extra giggle power! Warning: Side effects may include heart-thief vibes and spontaneous dance parties. 💜🤖💃\n",
      "\n",
      "Hashtags:  \n",
      "#ViralVibes #UltraFamousBlogger #CutieAlert #QuirkyContent #InstaFun #SpreadTheLove #DancingIntoFame #RobotLife #InstaFamous #FeedGoals\n"
     ]
    }
   ],
   "execution_count": 8
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-15T11:05:16.999242Z",
     "start_time": "2025-08-15T11:05:13.073152Z"
    }
   },
   "cell_type": "code",
   "source": [
    "runBlocking {\n",
    "    val response = executor.executeStreaming(prompt = prompt, model = OpenAIModels.Chat.GPT4_1)\n",
    "    response.collect { print(it) }\n",
    "}"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Caption:  \n",
      "Running on good vibes & wi-fi only! 🤖💜 Drop a like if you feel the circuit-joy! #BlogBotInTheWild #HeartDeliveryService #DancingWithWiFi #UltraFamousBlogger #MoreFunThanYourAICat #ViralVibes #InstaFun #BeepBoopFamous"
     ]
    }
   ],
   "execution_count": 10
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Kotlin",
   "language": "kotlin",
   "name": "kotlin"
  },
  "language_info": {
   "name": "kotlin",
   "version": "2.2.20-Beta2",
   "mimetype": "text/x-kotlin",
   "file_extension": ".kt",
   "pygments_lexer": "kotlin",
   "codemirror_mode": "text/x-kotlin",
   "nbconvert_exporter": ""
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
